package org.catpay.modules.sys.oauth2;

import java.util.Set;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.Sha256Hash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.catpay.common.utils.JsonUtil;
import org.catpay.common.utils.RedisUtils;
import org.catpay.modules.sys.entity.SysUserEntity;
import org.catpay.modules.sys.service.ShiroService;
import org.catpay.modules.sys.service.SysUserRoleService;
import org.catpay.modules.sys.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;


@Component
public class UserRealm extends AuthorizingRealm {
	

	@Lazy
	@Autowired
	private SysUserService sysUserService;
	
	@Lazy
    @Autowired
    private ShiroService shiroService;
    
	@Lazy
    @Autowired
    private RedisUtils redisUtils;
	
	@Lazy
	@Autowired
	private SysUserRoleService sysUserRoleService;

	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		SysUserEntity user = (SysUserEntity) principals.getPrimaryPrincipal();
		Long userId = user.getUserId();
		// 用户权限列表
		Set<String> permsSet = shiroService.getUserPermissions(userId);
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setStringPermissions(permsSet);
		return info;
	}

	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
		String userName = token.getPrincipal().toString();
		String passWord = new String((char[]) token.getCredentials());
		SysUserEntity user = sysUserService.queryByUserName(userName);
		if (user == null || !user.getPassword().equals(new Sha256Hash(passWord, user.getSalt(),1024).toHex())) {
			throw new UnknownAccountException("用户名或者密码出错!");
		}
		if (user.getStatus() == 0) {
			throw new LockedAccountException("账号已被锁定,请联系管理员!");
		}

		//获取登录用户角色ID
		user.setRoleIdList(sysUserRoleService.queryRoleIdList(user.getUserId()));
		
		// 登陆认证
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), this.getName());
		// 设置盐值
		info.setCredentialsSalt(ByteSource.Util.bytes(user.getSalt()));
		//清除认证缓存
		redisUtils.delete(JsonUtil.getInstance().obj2json(user));
		return info;
	}

}
